#ifndef _FRAMEBUFFER_H_
#define _FRAMEBUFFER_H_

#include <stdint.h>
#include <memory>
#include <functional>
#include <optional>

namespace SEngine
{
    enum Attachment;
    class FrameBufferLoader;
    class Texture2D;
    class FrameBuffer final
    {
        struct AttachmentInfo
        {
            std::optional<std::reference_wrapper<Texture2D>> texture;
            int target;
            int mipLevels = 0;
        };
        friend class FrameBufferLoader;
    public:
        FrameBuffer();
        virtual ~FrameBuffer();
        void Resize(int w, int h);
        void Bind();
        void Unbind();
        void ClearAttachments();
        void EnableRenderBuffer(bool value) { m_hasRenderBuffer = value; }
        void Use();
        std::optional<std::reference_wrapper<Texture2D>> SwapAttachments(Attachment, Texture2D & tex);
        std::optional<std::reference_wrapper<Texture2D>> SwapAttachments(Attachment, Texture2D & tex, int textarget, int mipLevels = 0);
        std::optional<std::reference_wrapper<Texture2D>> GetAttachment(Attachment attachment);
    protected:
        uint32_t m_fbo;
        uint32_t m_rbo;
        std::unordered_map<Attachment, AttachmentInfo> m_attachments;
        std::function<void(int w, int h)> m_resizeFn;
        bool m_hasRenderBuffer{true};
    };
} // namespace SEngine


#endif